//this program produces makefiles used to create the csp solver.
//It runs off of a .mass file. 

#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <map>

using namespace std;

const string p1="CC = g++";
const string p2="CXXFLAGS = -O2 -Wall -DMAC_HEADER_FILE=\\\"mac3all.h\\\"";
const string p3="OBJECTS = testMAC3all.o backtracking.o next_variable.o mac3all.o csp_base.o urbcsp.o resourcesUsageCounter.o bsupport.o";
const string p4="csp.out: $(OBJECTS)\n\t$(CC) $(CXXFLAGS) $(OBJECTS) -o csp.out";
const string p5="backtracking.o: backtracking.cpp backtracking.h mac3all.h";
const string p6="\t$(CC) -c $(CXXFLAGS) $< -o $@";
const string p7="%.o: %.cpp %.h\n\t$(CC) -c $(CXXFLAGS) $< -o $@ ";

void makeMakefile(ostream&,string&,string&,map<string,string>&);

int main(int argc,char *argv[])
{
	if(argc!=2)
		return 1;
	map<string,string> converter;
	converter["AC3"]="-DUSEAC3";
	converter["AC31"]="-DUSEAC31";
	converter["AC31R"]="-DUSEAC31R";
	converter["AC311"]="-DUSEAC311";
	converter["AC3R"]="-DUSEAC3R";
	converter["AC3DR"]="-DUSEAC3DR";
	converter["AC3FDR"]="-DUSEAC3FDR";
	converter["AC3DFR"]="-DUSEAC3DFR";
	converter["AC3ADR"]="-DUSEAC3ADR";
	converter["AC3RDR"]="-DUSEAC3RDR";
	converter["AC3AFDR"]="-DUSEAC3AFDR";
	converter["AC3SFR"]="-DUSEAC3SFR";
	converter["AC3C"]="-DUSEAC3C";
	converter["AC3T"]="-DUSEAC311 -DTAIL_DOMAIN -DORDERED_DOMAIN";
	converter["AC3ADO2"]="-DUSEAC3BADO -DTAIL_DOMAIN -DBACK_POINT_SUPPORT -DORDERED_DOMAIN";
	converter["NP"]="-DPRUNE=pruneNone -DVR=noPruneNext";
	converter["P"]="-DPRUNE=pruneSingle";
	converter["NF"]="-DVR=varNext";
	converter[""]="-DVR=varNextForceOld";
	converter["NPD"]=""; //special conversion to prevent NoPrune from being overrun
	converter["D2"]="-DVR=varNextForceOld -DDOMAINSPLIT -DSEG_SIZE=2";
	converter["D3"]="-DVR=varNextForceOld -DDOMAINSPLIT -DSEG_SIZE=3";
	converter["PR"]="pagerank3";
	converter["PD"]="pagerankD";
	converter["NB"]="H_1_DD_plus";
	converter["DD"]="DD";
	converter["DY"]="DyDD";
	converter["DE"]="deg";
	converter["DO"]="dom";
	converter["FD"]="futdeg";


	ofstream insout("totaldata.txt",ios::trunc);
	ofstream avgout("Avgdata.txt",ios::trunc);
	ifstream masscon(argv[1]);
	int AC_types;
	masscon >> AC_types;
	cout << "There are " << AC_types << " of AC types to compile." << endl;
	for(int ac=0;ac<AC_types;ac++)
	{
		string ac_suffix;
		masscon >> ac_suffix;
		int heur_types;
		masscon >> heur_types;
		cout << "There are " << heur_types << " of heuristic combinations for " << ac_suffix << endl;
		for(int h=0;h<heur_types;h++)
		{
			string heur_prefix;
			masscon >> heur_prefix;
			ostringstream filen;
			filen << heur_prefix << ac_suffix << ".make";
			cout << "Creating " << filen.str() << endl;
			ofstream makefile(filen.str().c_str());
			string reqs;
			masscon >> reqs;
			makeMakefile(makefile,reqs,ac_suffix,converter);
			makefile.close();
		}
	}
}

void makeMakefile(ostream& makefile,string& reqs,string& ac,map<string,string>& converter)
{
	char test;
	int pos=0;
	string vheur,pheur,dheur;
	vheur=reqs.substr(pos,2);
	test=reqs[2];
	pos+=2;
	if(test=='N')
	{
		pheur=reqs.substr(pos,2);
		pos+=2;
	}
	else
	{
		pheur=reqs.substr(pos,1);
		pos++;
	}
	test=reqs[pos];
	if(test=='N' || test=='D')
	{
		dheur=reqs.substr(pos,2);
		pos+=2;
	}
	else
	{
		dheur="";
	}

	if(pheur=="NP")
		dheur="NPD";

	makefile << p1 << endl << endl << p2 << " -DNEXTVAL=next -DCHOOSENEXTVAR=";
	makefile << converter[vheur] << ' ' << converter[pheur] << ' ' << converter[dheur] << ' ' << converter[ac] << endl;
	makefile << p3 << endl << p4 << endl << p5 << endl << p6 << endl << p7 << endl;
}



 

